/**
 * 65. 有效数字
 * https://leetcode-cn.com/problems/valid-number/
 */
public class Solutions_65 {
    public static void main(String[] args) {
//        String str = "0";  // output: true
//        String str = " 0.1 ";  // output: true
//        String str = "abc";  // output: false
//        String str = "1 a";  // output: false
//        String str = "2e10";  // output: true
//        String str = " -90e3 ";  // output: true
        String str = " 1e";  // output: false
//        String str = "e3";  // output: false
//        String str = " 6e-1";  // output: true
//        String str = " 99e2.5";  // output: false
//        String str = "53.5e93";  // output: true
//        String str = " --6 ";  // output: false
//        String str = "-+3";  // output: false
//        String str = "95a54e53";  // output: false

        boolean result = isNumber(str);
        System.out.println(result);
    }

    /**
     * 除了几种不合法的情况，其他的情况都视为合法
     * 关键：出现科学计数符号后，需要将数字标记为未出现过，并在最后结果返回时，判断数字是否出现过
     * 即出现科学计数符号后，后面必须再跟着数字，表明幂的次数
     */
    public static boolean isNumber(String s) {
        if (s == null && s.length() < 1) {
            return true;
        }
        // 去除字符串前后的空格后，转化为字符数组
        char[] arr = s.trim().toCharArray();
        // 是否出现过数字
        boolean numFlag = false;
        // 是否出现过科学计数符号 e, E
        boolean eFlag = false;
        // 是否出现过小数点
        boolean dotFlag = false;

        for (int i = 0; i < arr.length; i++) {
            char c = arr[i];
            if (Character.isDigit(c)) {
                // 出现数字时：标记数字已经出现
                numFlag = true;
            } else if (arr[i] == '.') {
                // 出现小数点时
                if (eFlag || dotFlag) {
                    // 不合法的情况：小数点出现过，科学计数符号出现过
                    return false;
                }
                // 标记小数点已经出现
                dotFlag = true;
            } else if (arr[i] == '-' || arr[i] == '+') {
                // 出现运算符号时
                if (i > 0 && !(arr[i - 1] == 'e' || arr[i - 1] == 'E')) {
                    // 不合法的情况：不在首位时，前面一位不是科学计算符号 e, E
                    return false;
                }
            } else if (arr[i] == 'e' || arr[i] == 'E') {
                // 出现科学计数符号时
                if (!numFlag || eFlag) {
                    // 不合法的情况：未出现过数字，或者科学计数符号已经出现过
                    return false;
                }
                eFlag = true;
                // 将数字标记为未出现过
                numFlag = false;
            } else {
                // 'a', 'b', ' ' 等其他字符都不合法
                return false;
            }
        }
        // 12e = false，最终还要判断数字是否出现过
        return numFlag;
    }
}
